package kr.snake75.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.snake75.annotation.RequestParam;
import kr.snake75.annotation.Result;
import kr.snake75.annotation.ResultAttr;

import org.apache.log4j.Logger;

public class Invoker {
	private static final Logger logger = Logger.getLogger(Invoker.class);
	private Method method;
	private Object object;
	
	public Invoker(Method method, Object object) {
		this.method = method;
		this.object = object;
	}
	
	public void invoke(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info(method);
		logger.info(object);

		int idx = 0;

		Object[] objParamList = null;
		
		Annotation[][] paramAnnos = method.getParameterAnnotations();
		objParamList = new Object[paramAnnos.length];
		
		for(Annotation[] tempAnnos : paramAnnos) {
			for(Annotation tempAnno: tempAnnos) {
				if(tempAnno.annotationType() == RequestParam.class) {
					RequestParam reqParam = (RequestParam) tempAnno;
					String value = reqParam.value();
					String className = reqParam.classpath();
					
					logger.info("value     ==> " + value);
					logger.info("className ==> " + className);

					if(value.equals(RequestParam.SESSION)) {
						objParamList[idx] = request.getSession();
					} else if (value.equals(RequestParam.DTO)) {
						objParamList[idx] = ParameterUtil.makeVO(request, className);
					} else {
						objParamList[idx] = request.getAttribute(value);
					}
				}
			} // Annotation tempAnno: tempAnnos
			idx++;
		} // Annotation[] tempAnnos : paramAnnos
		
		
		Result result = method.getAnnotation(Result.class);

		if(result == null) {		
			RequestDispatcher dispatcher = request.getRequestDispatcher(method.getName() + ".jsp");
			dispatcher.forward(request, response);
		}
		
		Object returnObj = method.invoke(object, objParamList);
		
		if(method.isAnnotationPresent(ResultAttr.class) == true) {
			ResultAttr attr = method.getAnnotation(ResultAttr.class);
			
			request.setAttribute(attr.value(), returnObj);
		}
				
		if(result.redirect() == true) {
			RequestDispatcher dispatcher = request.getRequestDispatcher(result.value());
			dispatcher.forward(request, response);
		}
	}
}
